#include <arch/cpu.h>
#include <sys/sysdef.h>
#include <sys/unistd.h>
#include <mm/valloc.h>
#include <mm/slab.h>
#include <mm/memregion.h>
#include <process.h>
#include <log.h>

struct process process_table[MAX_PROCESS];

volatile struct process* cur_proc = process_table;

lnode_t kthread_list;

kmem_cache_t* mm_kmem_cache;

__DEF_SYSCALL0(pid_t, getpid) {
    return cur_proc->pid;
}

void process_init() {
    memset(process_table, 0, sizeof(process_table));
    cur_proc = process_table;
    cur_proc->state = PROCESS_RUNNING;
    cur_proc->cr3 = cpu_rcr3();
    cur_proc->fd_table = vzalloc(sizeof(fd_table_t));
    list_head_init(&cur_proc->waitq);
    list_head_init(&cur_proc->threads);
    list_head_init(&kthread_list);

    mm_kmem_cache = new_kmem_cache("mm_kmem_cache", sizeof(struct mm), 1, 0);
}

struct mm* mm_alloc(struct process* proc) {
    struct mm* mm = take_obj(mm_kmem_cache);
    memset(mm, 0, sizeof(struct mm));

    mm->ustack_top = KERNEL_MM_BASE - 0x10;
    mm->ustack_bottom = KERNEL_MM_BASE - USTACK_SIZE;
    mm->proc = proc;

    atomic_init(&mm->ref_count, 1);
    mutex_init(&mm->lock);

    return mm;
}

void mm_free(struct mm* mm) {
    release_obj(mm_kmem_cache, mm);
}
